<?php

namespace StudyBuddy\Api\v1;

use \StudyBuddy\Api\Api;
use \StudyBuddy\QuestionParser;
use \StudyBuddy\String\HTMLString;

/**
 * Controller for adding new Quetion via
 * API POST
 *
 */
class Addquestion extends Api {

    protected $bRequirePost = true;
    protected $membersOnly = true;
    protected $permission = 'ask';

    /**
     * Object of newly created Question
     *
     * @var object of type \StudyBuddy\Question
     */
    protected $oQuestion;
    protected $aRequired = array('qbody', 'title');

    /**
     * Object representing data of the submitted
     * question.
     *
     * @var Object of type SubmittedQuestionApi
     * extends SubmittedQuestionWWW
     *
     */
    protected $oSubmitted;

    protected function main() {

        $this->oSubmitted = new SubmittedQuestion($this->oRegistry);

        $this->validateTitle()
                ->validateBody()
                ->validateTags()
                ->process()
                ->setOutput();
    }

    /**
     * Validate title length
     *
     * @return object $this
     */
    protected function validateTitle() {
        $t = $this->oSubmitted->getTitle();
        $min = $this->oRegistry->Ini->MIN_TITLE_CHARS;
        d('min title: ' . $min);
        if ($this->oSubmitted->getTitle()->htmlentities()->trim()->length() < $min) {
            throw new \StudyBuddy\HttpResponseCodeException('Title must contain at least ' . $min . ' letters', 400);
        }

        return $this;
    }

    /**
     * Validate min number of words in question
     * and min number of chars in question
     *
     * @return object $this
     */
    protected function validateBody() {

        $minChars = $this->oRegistry->Ini->MIN_QUESTION_CHARS;
        $minWords = $this->oRegistry->Ini->MIN_QUESTION_WORDS;
        $body = $this->oSubmitted->getBody();
        $oHtmlString = HTMLString::factory($body);
        $wordCount = $oHtmlString->getWordsCount();
        $len = $oHtmlString->length();

        if ($len < $minChars) {
            throw new \StudyBuddy\HttpResponseCodeException('Question must contain at least ' . $minChars . ' letters', 400);
        }

        if ($wordCount < $minWords) {
            throw new \StudyBuddy\HttpResponseCodeException('Question must contain at least ' . $minWords . ' words', 400);
        }

        return $this;
    }

    /**
     * Validate to enforce at least one tag
     * and not more that value MAX_QUESTION_TAGS in settings
     *
     * @return object $this
     */
    protected function validateTags() {
        $min = $this->oRegistry->Ini->MIN_QUESTION_TAGS;
        $max = $this->oRegistry->Ini->MAX_QUESTION_TAGS;

        $aTags = $this->oSubmitted->getTagsArray();
        $count = count($aTags);

        if ($count > $max) {
            throw new \StudyBuddy\HttpResponseCodeException('Question cannot have more than ' . $max . ' tags. Please remove some tags', 400);
        }

        if ($count < $min) {
            throw new \StudyBuddy\HttpResponseCodeException('Question must have at least ' . $min . ' tag(s)', 400);
        }

        return $this;
    }

    /**
     *
     * Process submitted form values
     * and create the $this->oQuestion object
     */
    protected function process() {

        $oAdapter = new QuestionParser($this->oRegistry);
        try {
            $this->oQuestion = $oAdapter->parse($this->oSubmitted);
            d('cp created new question');
            d('title: ' . $this->oQuestion['title']);
        } catch (\StudyBuddy\QuestionParserException $e) {
            $err = $e->getMessage();
            d('$err: ' . $err);

            throw new \StudyBuddy\HttpResponseCodeException($err, 400);
        }

        return $this;
    }

    /**
     * Entire Question data will be returned
     * in request
     *
     * @return object $this
     */
    protected function setOutput() {

        $this->oOutput->setData($this->oQuestion->getArrayCopy());

        return $this;
    }

}
